﻿using System.Drawing;

namespace Rsdn.Janus
{
    using System;
    using System.Collections.Generic;
    using System.Windows.Forms;
    using CoreServices.NavigationTree;

    internal class VirtualForum : Forum
    {
        private readonly IVirtualForumProvider virtualForumProvider;
        MessageCounters messageCounters = new MessageCounters();
        private Action<int, MessageCounters> loadCountersAction;
        private Func<bool, MessageCounters, IMsg> loadTopicsAsChildrenFunc;

        public VirtualForum(IServiceProvider provider, IVirtualForumProvider virtualForumProvider)
            : base(provider)
        {
            this.virtualForumProvider = virtualForumProvider;
            if (virtualForumProvider != null)
            {
                loadCountersAction = virtualForumProvider.LoadCountersAction;
                loadTopicsAsChildrenFunc = virtualForumProvider.LoadTopicsAsChildrenFunc;

                IIncomingFolderUpdate folderUpdate = (IIncomingFolderUpdate)provider.GetService(typeof(IIncomingFolderUpdate));
                folderUpdate.AddUpdate(this);
                INavigationTreeItemInfo itemInfo = virtualForumProvider.GetItemInfo(string.Empty);
                if (itemInfo != null)
                {
                    Name = itemInfo.DisplayNameFunc();
                    ID = ConvertToVirtualId(itemInfo.Id);
                }
            }
        }

        private int ConvertToVirtualId(int id)
        {
            return (id & 0xFFFF) << 16;
        }

        /// <summary>
        /// Clears this forum.
        /// </summary>
        public void Clear()
        {
            ActiveMsg = null;
        }

        internal override void LoadCounters(int id)
        {
            if (loadCountersAction != null)
            {
                loadCountersAction(id, messageCounters);
                MessagesCount = messageCounters.MessagesCount;
                RepliesToMeUnread = messageCounters.RepliesToMeUnread;
                Unread = messageCounters.Unread;
            }
            else
            {
                base.LoadCounters(id);
            }
        }

        /// <summary>
        /// Загружает данные.
        /// Так как данные загружаются только при непосредственном выборе раздела
        /// То здесь загружаем только счетчики
        /// </summary>
        /// <param name="isLoadAll">if set to <c>true</c> [is load all].</param>
        internal override void LoadData(bool isLoadAll)
        {
            LoadCounters(0);
        }

        protected override IMsg LoadTopicsAsChildren(bool isLoadAll)
        {
            IMsg ret = null;

            if (loadTopicsAsChildrenFunc != null)
            {
                ret = loadTopicsAsChildrenFunc(isLoadAll, messageCounters);
                if (ret != null)
                {
                    MessagesCount = messageCounters.MessagesCount;
                    RepliesToMeUnread = messageCounters.RepliesToMeUnread;
                    Unread = messageCounters.Unread;
                }
            }
            return ret;
        }

        /// <summary>
        /// Creates the GUI control.
        /// </summary>
        /// <returns></returns>
        protected override Control CreateGuiControl()
        {
            Control control = null;
            if (virtualForumProvider != null)
            {
                control = virtualForumProvider.CreateGuiControl();
            }

            if (control == null)
            {
                VirtualForumDummyForm forumDummyForm = VirtualForumDummyForm.Instance;
                forumDummyForm.VirtualForumId = ID;
                control = forumDummyForm;
            }
            return control;
        }

        /// <summary>
        /// Occurs when [active messages changed].
        /// </summary>
        public override event EventHandler ActiveMessagesChanged
        {
            add { VirtualForumDummyForm.Instance.SelectedMessagesChanged += value; }
            remove { VirtualForumDummyForm.Instance.SelectedMessagesChanged -= value; }
        }

        protected override Image GetForumImage()
        {
            Image forumImage = base.GetForumImage();
            if (virtualForumProvider != null)
            {
                INavigationTreeItemInfo navigationTreeItemInfo = virtualForumProvider.GetItemInfo("");
                if (navigationTreeItemInfo != null && navigationTreeItemInfo.ItemImage != null)
                {
                    forumImage = navigationTreeItemInfo.ItemImage;
                }
            }
            return forumImage;
        }

        /// <summary>
        /// Детали реализации FindMsgByID...
        /// </summary>
        /// <param name="idMsg">ID сообщения которое нужно найти.</param>
        /// <returns>Найденая ветка.</returns>
        public override IMsg FindMsgById(int idMsg)
        {
            IMsg root = Msgs;
            IMsg ret = null;
            foreach (MsgBase msg in root)
            {
                if (msg.ID == idMsg)
                {
                    ret = msg;
                    break;
                }
            }
            return ret;
        }

        /// <summary>
        /// Sets the active MSG.
        /// </summary>
        /// <param name="value">The value.</param>
        protected override void SetActiveMsg(IMsg value)
        {
            lock (this)
            {
                if (value == null)
                {
                    //ActiveMsgId = -1;
                    ActiveMsgTarget = null;

                    // by init we use clear forum and it clear last saved message id
                    //Config.Instance.RemoveLastReadMessageInForum(ID);

                    return;
                }

                if (value == WeakMsgRoot.Target)
                {
                    return;
                }

                IMsg curr = value;
                //IMsg root = Msgs;

                //while (curr.Parent != null)

                //if (root == curr.Parent)
                {
                    //ActiveMsgId = value.ID;
                    ActiveMsgTarget = value;
                    Control guiControl = GuiControl;

                    Config.Instance.SetLastReadMessageInForum(ID, ActiveMsgId);
                    return;
                }

                //string message = string.Format("Сообщение '{0}' отсутствует в списке сообщений.", value);

                //throw new ApplicationException(message);
            }
        }

        /// <summary>
        /// Gets the active messages.
        /// </summary>
        /// <value>The active messages.</value>
        public override IEnumerable<IMsg> ActiveMessages
        {
            get
            {
                return VirtualForumDummyForm.Instance.SelectedMessages;
            }
        }


        /// <summary>
        /// Gets the description.
        /// </summary>
        /// <value>The description.</value>
        public override string Description
        {
            get
            {
                return Name;
            }
        }

        /// <summary>
        /// Gets the key.
        /// </summary>
        /// <value>The key.</value>
        public override string Key
        {
            get
            {
                string key = "None"; // MLHIDE
                if (virtualForumProvider != null)
                {
                    INavigationTreeItemInfo itemInfo = virtualForumProvider.GetItemInfo("");
                    if (itemInfo != null)
                    {
                        key = itemInfo.ItemKey;
                    }
                }
                else
                {
                    key = GetType().Name;
                }

                return key;
            }
        }

        /// <summary>
        /// Gets a value indicating whether this instance is virtual.
        /// Получает значение, указывающее, является ли этот форум виртуальным
        /// </summary>
        /// <value>
        ///   <c>true</c> if this instance is virtual; otherwise, <c>false</c>.
        /// </value>
        public override bool IsVirtual
        {
            get
            {
                return true;
            }
        }

    }
}